package cn.ichiva.dl.tushare.analy.ws;

import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket 基础
 *
 * 进行基本的连接状态维护
 */
@Slf4j
public abstract class SessionWebSocketServer extends WebSocketServer {
    public static final String SESSIONS_KEY = "sessions";

    protected final ConcurrentHashMap<WebSocket, WebsocketSession> sessions = new ConcurrentHashMap<>();
    private final InetSocketAddress inetSocketAddress;

    public SessionWebSocketServer(InetSocketAddress inetSocketAddress) {
        super(inetSocketAddress);
        this.inetSocketAddress = inetSocketAddress;
    }

    @Override
    public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
        WebsocketSession session = new WebsocketSession();
        session.setWebSocket(webSocket);
        session.put(SESSIONS_KEY,sessions);
        sessions.put(webSocket, session);
        log.info("客户接入 size = {}",sessions.size());

        onOpen(session);
    }

    @Override
    public void onMessage(WebSocket conn, String message) {
        WebsocketSession session = sessions.get(conn);
        onMessage(session,message);
    }

    @Override
    public void onMessage(WebSocket conn, ByteBuffer message) {
        WebsocketSession session = sessions.get(conn);
        onMessage(session,message);
    }

    @Override
    public void onError(WebSocket webSocket, Exception e) {
        log.warn("WebSocket 链接异常!",e);
    }

    @Override
    public void onClose(WebSocket webSocket, int code, String reason, boolean remote) {
        WebsocketSession session = sessions.remove(webSocket);
        log.info("{} 代码 {}, 当前连接数 = {},附加信息:",remote?"远程断开":"本地断开",code,sessions.size(),reason);
        onClose(session);
    }

    protected void onOpen(WebsocketSession session){};
    protected void onMessage(WebsocketSession session,String message){};
    protected void onMessage(WebsocketSession session,ByteBuffer message){};
    protected void onClose(WebsocketSession session){};

    @Override
    public void onStart() {
        log.info("ws://{}:{}",inetSocketAddress.getHostName(),inetSocketAddress.getPort());
    }
}
